package com.nali.dal.mongo.dao.general;

import java.util.List;

import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.WriteConcern;
import com.nali.dal.dao.general.IGeneralOperateDao;
import com.nali.dal.ds.IDataSource;
import com.nali.dal.ds.UsingDataSource;
import com.nali.dal.exception.SyntaxException;
import com.nali.dal.expression.ExpressionDto;
import com.nali.dal.expression.ExpressionValue;
import com.nali.dal.expression.PropertyExpression;
import com.nali.dal.expression.operate.Modifier;
import com.nali.dal.expression.query.Criteria;
import com.nali.dal.mongo.explain.operate.PreparedUpdate;
import com.nali.dal.mongo.explain.operate.Update;

public class MongoGeneralOperateDao implements IGeneralOperateDao, UsingDataSource<DB> {
	private DB db;
	private WriteConcern concern=WriteConcern.SAFE;
	
	public MongoGeneralOperateDao() {
		super();
	}

	public MongoGeneralOperateDao(WriteConcern concern, IDataSource<DB> ds) {
		this(concern, ds.getConnection());
	}

	public MongoGeneralOperateDao(WriteConcern concern, DB db) {
		super();
		this.concern = concern;
		this.db = db;
	}

	@Override
	public void setDataSource(IDataSource<DB> ds) {
		this.db = ds.getConnection();		
	}
	
	@Override
	public int update(String collectionName, ExpressionDto<Criteria> query, List<ExpressionValue<Modifier>> modifiers) {
		return doUpsert(collectionName, query, modifiers, false);
	}

	private int doUpsert(String collectionName, ExpressionDto<Criteria> query, List<ExpressionValue<Modifier>> modifiers, boolean upsert) {
		DBCollection collection = db.getCollection(collectionName);
		List<ExpressionValue<Criteria>> expressionValues = query.getExpressionValues();
		List<PropertyExpression<Criteria>> propertyExpressions = query.getPropertyExpressions();
		PreparedUpdate pu = Update.parse(expressionValues, propertyExpressions, modifiers);
		if(pu.getConditionParamSize()!=0) {
			throw new SyntaxException("missing "+pu.getConditionParamSize()+" query value");
		}
		try {
			return pu.update(collection, upsert, concern);
		} catch (Exception e) {
			throw ExceptionTraner.tranException(e);
		}
	}

	@Override
	public int upsert(String collectionName, ExpressionDto<Criteria> query, List<ExpressionValue<Modifier>> modifiers) {
		return doUpsert(collectionName, query, modifiers, true);
	}

}
